<?php

namespace Lvzmen\Apifox;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Lvzmen\Helper\iArrayHelper;

class Doc
{
    private $projectId; // 21***69
    private $token;     // APS-PbMdZ0nu************UQu9nZKNbtfB
    private $table;     // 表名称，从表中获取字段说明
    private $filePath;  // 临时文件路径
    private $dbConnection;  // 数据库的链接
    private $db;        // 数据库的名字
    private $response;

    public function __construct($table = '')
    {
        $this->token = env('APIFOX_TOKEN', '');
        $this->projectId = env('APIFOX_PROJECT_ID', '');
        $this->filePath = env('APIFOX_FILE_PATH', '/tmp/api_fox.cnf');
        $this->dbConnection = env('APIFOX_DB_CONNECTION', '');
        $this->db = env('APIFOX_DB', '');
        $this->table = $table;
        $this->response = json_decode($this->getFromFile(), 1);
    }

    protected function send($data)
    {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => 'https://api.apifox.cn/api/v1/projects/' . $this->projectId . '/import-data?locale=zh-CN',
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_HTTPHEADER => array(
                'X-Project-Id: ' . $this->projectId,
                'X-Apifox-Version: 2022-11-16',
                'Authorization: Bearer ' . $this->token,
                'User-Agent: Apifox/1.0.0 (https://www.apifox.cn)',
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        $result = json_decode($response, 1);
        if (isset($result['data']['apiCollection']['item'])) {
            var_dump($result['data']['apiCollection']['item']);
        } else {
            var_dump($response);
        }
    }

    /**
     * Perform any final actions for the request lifecycle.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Http\Response $response
     * @return void
     */
    public function saveToFile($request, $response)
    {
        $result = [
            'url' => $request->getRequestUri(),
            'method' => $request->method(),
            'query' => $request->query(),
            'response' => $response->getContent()
        ];
        $result = json_encode($result);
        file_put_contents($this->filePath, $result);
    }

    protected function getFromFile()
    {
        return file_get_contents('/tmp/api_fox.cnf');
    }


    protected function getQuery()
    {
        $content = json_decode($this->getFromFile(), 1);
        $query = $content['query'] ?? [];
        $result = [];
        foreach ($query as $name => $value) {
            $result[] = [
                'name' => $name,
                'description' => '',
                'type' => is_numeric($value) ? 'number' : gettype($value),
                "sampleValue" => $value,
                'required' => false,
            ];
        }
        return $result;
    }

    protected function getResponse()
    {
        $content = json_decode($this->getFromFile(), 1);
        $response = $content['response'] ?? '{}';
        $response = json_decode($response, 1);
        $result = [[
            "name" => "成功",
            "code" => 200,
            "jsonSchema" => $this->getColumnDefined($response)
        ]];
//        jsonSchema:
//        [
//            "type" => "object",
//            "properties" => [
//                'msg' => [
//                    'type' => 'string',
//                    'description' => '',
//                ],
//                'data' => [
//                    "type" => "array",
//                    "items" => [
//                        "type" => 'object',
//                        'properties' => [
//                            'id' => [
//                                'type' => 'number',
//                                'description' => '',
//                            ]
//                        ]
//                    ]
//                ]
//            ],
//        ]
        iArrayHelper::setValue($result, '0.jsonSchema.properties.code.type', 'integer');
        iArrayHelper::setValue($result, '0.jsonSchema.properties.code.description', '');
        return $result;
    }

    private function getColumnDefined($data)
    {
        $result = [];
        if (iArrayHelper::isAssociative($data)) {
            // 对象类型的数据
            $result['type'] = 'object';
            $result['properties'] = [];
            foreach ($data as $key => $value) {
                if (!is_array($value)) {
                    $result['properties'][$key] = [
                        'type' => $this->getColumnType($key, $value),
                        'description' => $this->getColumnDesc($key)
                    ];
                } else {
                    $result['properties'][$key] = $this->getColumnDefined($value);
                }
            }
        } else {
            // 数值类型数据
            $result['type'] = 'array';
            $result['items'] = $this->getColumnDefined($data[0] ?? []);
        }

        return $result;
    }

    private function getColumnType($name, $value)
    {
        $data = json_decode(file_get_contents(database_path() . '/data/apifox.json'), 1);
        if ($this->table == '') {
            return 'string';
        } else {
            $tables = explode('.', $this->table);
            foreach ($tables as $table) {
                return $data[$table][$name]['type'] ?? (is_numeric($value) ? 'number' : gettype($value));
            }
        }

    }

    private function getColumnDesc($name = '')
    {
        if ($this->table == '') return '';
        $tables = explode('.', $this->table);
        $result = '';
        foreach ($tables as $table) {
            if (Schema::connection($this->dbConnection)->hasTable($table)) {
                $desc = DB::connection($this->dbConnection)->select("
                    SELECT
                           COLUMN_COMMENT
                    FROM INFORMATION_SCHEMA.COLUMNS
                    WHERE TABLE_SCHEMA = '{$this->db}'
                        AND TABLE_NAME = '" . $table . "'
                        AND COLUMN_NAME = '" . $name . "'
                ");

                if (!empty($desc)) {
                    $result = $desc[0]->COLUMN_COMMENT;
                }
                // return $result;
            } else {
                $data = json_decode(file_get_contents(database_path() . '/data/apifox.json'), 1);
                if (isset($data[$table][$name])) {
                    $result = $data[$table][$name]['desc'] ?? ($data[$table][$name] ?? '');
                }
            }
        }
        return $result;
    }

    protected function getResponseExamples()
    {
        $content = json_decode($this->getFromFile(), 1);
        $response = $content['response'] ?? '{}';
        $response = json_decode($response, 1);

        return [[
            "name" => "成功示例",
            "code" => 200,
            "data" => json_encode($response)
        ]];
    }

    public function getUri()
    {
        $uri = explode('?', $this->response['url']);
        return $uri[0] . '/';
    }

    public function createApi()
    {
        $data = [
            'data' => [
                'httpCollection' => [
                    [
                        'name' => "Lvzmen",
                        'description' => "",
                        'items' => [
                            [
                                "name" => "接口名称",
                                "method" => $this->response['method'],
                                "path" => $this->getUri(),
                                "parameters" => [
                                    "query" => $this->getQuery()
                                ],
                                "responses" => $this->getResponse(),
                                "responseExamples" => $this->getResponseExamples(),
                                "requestBody" => [],
                                "tags" => [],
                            ]
                        ]
                    ]
                ]
            ]
        ];

        $data = json_encode($data);
        $this->send($data);
    }
}
